package com.haoze.nurseapp.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.haoze.common.constant.Constant;
import com.haoze.common.dto.*;
import com.haoze.common.enumeration.ConstantEnum;
import com.haoze.common.enumeration.StateEnum;
import com.haoze.common.exception.ServiceException;
import com.haoze.common.feign.DataSetValueCommonService;
import com.haoze.common.model.OrdersFileIndexDataEntity;
import com.haoze.common.model.OrdersFileIndexEntity;
import com.haoze.common.model.TaskExecuteBatchEntity;
import com.haoze.common.response.Result;
import com.haoze.common.response.ResultGenerator;
import com.haoze.common.utils.*;
import com.haoze.nurseapp.dao.*;
import com.haoze.nurseapp.dto.Notification;
import com.haoze.nurseapp.dto.Patient;
import com.haoze.nurseapp.dto.TargetUser;
import com.haoze.nurseapp.dto.ConditionDetailsDTO;
import com.haoze.nurseapp.dto.FileIndexDataDTO;
import com.haoze.nurseapp.enumeration.ElementVarForSpecialEnum;
import com.haoze.nurseapp.enumeration.OrderStatusEnum;
import com.haoze.nurseapp.enumeration.TaskEnum;
import com.haoze.nurseapp.model.*;
import com.haoze.nurseapp.service.NurseFileIndexService;
import com.haoze.nurseapp.service.NursePatientOrderService;
import com.haoze.nurseapp.service.NurseTeamService;
import com.haoze.nurseapp.vo.Element;
import com.haoze.nurseapp.vo.EmrFileData;
import oracle.sql.TIMESTAMP;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.bson.types.ObjectId;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.concurrent.ListenableFuture;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.script.ScriptException;
import java.io.BufferedReader;
import java.io.IOException;
import java.sql.Clob;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


@Service
public class NursePatientOrderServiceImpl implements NursePatientOrderService {

    private Logger logger = LoggerFactory.getLogger(NursePatientOrderServiceImpl.class);

    public static final String SWITCH_ON = "1";

    @Resource
    PatientOrderMapper patientOrderMapper;

    @Resource
    TaskExecuteDetailMapper taskExecuteDetailMapper;

    @Resource
    TaskExecuteMapper taskExecuteMapper;

    @Resource
    TaskExecuteBatchMapper taskExecuteBatchMapper;

    @Resource
    TaskNodeMapper taskNodeMapper;

    @Resource
    HspBasicValueMapper hspBasicValueMapper;

    @Resource
    TaskNodeConditionMapper taskNodeConditionMapper;

    @Resource
    private DataSetValueCommonService dataSetValueCommonService;

    @Resource
    TaskExecutorMapper taskExecutorMapper;

    @Resource
    EmrFileMapper emrFileMapper;

    @Resource
    PatientMapper patientMapper;

    @Resource
    TaskMapper taskMapper;

    @Resource
    NodeMapper nodeMapper;

    @Resource
    NurseFileIndexService emrFeignService;

    @Resource
    NurseTeamService nurseTeamService;

    private ExecutorService fixedThreadPool;

    @Resource
    EmrTemplateMapper emrTemplateMapper;

    @Resource
    EmrFileIndexEntityMapper emrFileIndexEntityMapper;

    @Resource
    DrugRationalUseMapper drugRationalUseMapper;

    @Resource
    SqlSessionFactory sqlSessionFactory;

    @Resource
    MongoTemplate mongoTemplate;

    @Resource
    KafkaTemplate kafkaTemplate;

    @Value("${socket.url}")
    private String socketUrl;

    public NursePatientOrderServiceImpl() {
        fixedThreadPool = Executors.newFixedThreadPool(10);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result createNextTaskNode(String currentDetailId, long batchNo, String userId, String groupId, String msgContent, String executeBeginTime, String orderQrCode,String stopFlag) {//, Boolean sendMsgFlag
        Map<String, String> user = patientOrderMapper.getUser(userId);
        //获取待执行节点的task_execute_detail
        TaskExecuteDetailEntity currentDetailEntity = taskExecuteDetailMapper.selectByPrimaryKey(currentDetailId);
        //获取待执行节点的task_execute
        TaskExecuteEntity taskExecuteEntity = taskExecuteMapper.selectByPrimaryKey(currentDetailEntity.getTaskExecuteId());
        //根据医嘱id获取医嘱信息
        PatientOrdersEntity patientOrders = patientOrderMapper.selectByPrimaryKey(taskExecuteEntity.getInpatorderdataId());
        String inpatorderdataId = patientOrders.getInpatorderdataId();
        logger.info("医嘱：{} 触发任务下一个节点 用户ID：{} 当前任务执行明细ID：{}", inpatorderdataId, userId, currentDetailId);
        LocalDateTime now = LocalDateTime.now();
//        now = now.plusSeconds(2);
        //判断是否是输液巡视节点，查找上一次是否是输液巡视/暂停输液，如果是，当前模板引用数据为新增输液——>其他标签，应该跳过，继续引用上一次输液巡视节点内容
        String isSyxs = patientOrderMapper.queryIsSyxs(currentDetailId, orderQrCode);
        //修改当前节点执行明细状态为已执行
        currentDetailEntity.setEndDatetime(DateUtil.localDateTime2Date(now));
        currentDetailEntity.setModifyTime(DateUtil.localDateTime2Date(now));
        currentDetailEntity.setStatus(TaskEnum.EXECUTED.getValue());
        taskExecuteDetailMapper.updateByPrimaryKeySelective(currentDetailEntity);
        TaskExecuteBatchEntity currentBatchEntity = taskExecuteBatchMapper.getLastBatchEntityByQrcode(orderQrCode);
        currentBatchEntity.initUpdate();
        currentBatchEntity.setStopDatetime(new Timestamp(DateUtil.localDateTime2Date(now).getTime()));
        currentBatchEntity.setExecutePersonId(userId);
        currentBatchEntity.setStatus(TaskEnum.EXECUTED.getValue());
        //2020-12-07 start
        currentBatchEntity.setStopFlag(stopFlag);
        //2020-12-07 end
        taskExecuteBatchMapper.updateByPrimaryKeySelective(currentBatchEntity);
        logger.info("医嘱：{} 状态已经执行。", currentBatchEntity);
        if (StringUtils.isBlank(orderQrCode)) {
            orderQrCode = currentBatchEntity.getQrCode();
            if (StringUtils.isBlank(orderQrCode)) {
                orderQrCode = inpatorderdataId;
            }
        }
        if (OrderStatusEnum.ORDER_STOP.getValue().equals(patientOrders.getExecStatus()) ||
                OrderStatusEnum.ORDER_CANCEL.getValue().equals(patientOrders.getExecStatus())) {
            logger.info("医嘱：{} 已被取消。", inpatorderdataId);
            return ResultGenerator.genOkResult();
        }
        logger.info("医嘱：已被取消1111");
        Map<String, String> map = hspBasicValueMapper.selectMavEmrCoreDictByDVId(patientOrders.getOrdersClassId());
        if (OrderStatusEnum.ORDER_TYPE_ONE.getValue().equals(map.get("DATA_VALUE")) && OrderStatusEnum.ORDER_STOP_HIS.getValue().equals(patientOrders.getExecStatusHis()) && patientOrders.getPlanEndDatetime() != null && patientOrders.getPlanEndDatetime().getTime() <= System.currentTimeMillis()) {
            logger.info("医嘱：{} 已被停止。", inpatorderdataId);
            return ResultGenerator.genOkResult();
        }
        logger.info("医嘱： 已被取消2222");
//        if (OrderStatusEnum.ORDER_EXECUTE5.getValue().equals(patientOrders.getExecStatus()) ||
//                OrderStatusEnum.ORDER_EXECUTE6.getValue().equals(patientOrders.getExecStatus())) {
//            patientOrders.setExecPersonId(user.get("personId"));
//            patientOrders.setExecDatetime(DateUtil.localDateTime2Date(now));
//            updateGroupOrders(patientOrders);
//        }
        TaskNodeEntity taskNodeEntity = taskNodeMapper.selectByPrimaryKey(currentDetailEntity.getTaskNodeId());
        //节点已出结果发送通知
        if (taskNodeEntity != null && !StateEnum.LEVEL_NO_NOTIFY.getValue().equals(taskNodeEntity.getNotifyLevel())) {
            sendNotice(taskNodeEntity, taskExecuteEntity, msgContent);
        }
        logger.info("医嘱：2222222222222222222222");
        //判断下个节点触发条件
//        now = now.plusSeconds(1);
        List<FileIndexDataDTO> dataEntityList = patientOrderMapper.getAllFileIndexDataByTaskForNurse(currentBatchEntity.getTaskBatchId());
        Condition condition = new Condition(TaskNodeConditionEntity.class);
        condition.createCriteria().andEqualTo("preTaskNodeId", taskNodeEntity.getTaskNodeId());
        condition.orderBy("priority");
        logger.info("查询触发条件医嘱：preTaskNodeId：{} 优先级: ",taskNodeEntity.getTaskNodeId());
        List<TaskNodeConditionEntity> taskConditions = taskNodeConditionMapper.selectByCondition(condition);
        boolean triggerNextNode = false;
        List<ConditionDetailsDTO> taskConditionElements = patientOrderMapper.getConditionElements(taskNodeEntity.getTaskNodeId());
//                Map<String, Map<String, Object>> datasetMap = getDatasetMap(taskConditionElements, taskExecuteEntity.getInpatNum());
        List<CompletableFuture<Tuple2<String, JSONObject>>> datasetFutures = getDatasetMap2(taskConditionElements, taskExecuteEntity.getInpatNum());
        Map<String, Map<String, Object>> datasetMap = new HashMap<>();
        try {
            CompletableFuture.allOf(datasetFutures.toArray(new CompletableFuture[0])).thenApply(v -> datasetFutures.stream().map(CompletableFuture::join)
                    .collect(Collectors.toList())).get().stream().filter(Objects::nonNull).forEach(tuple2 -> datasetMap.put(tuple2.getT1(), tuple2.getT2()));
        } catch (Exception e) {
            logger.error("查询第三方接口出现错误。", e);
        }
        logger.error("获取病人数据{}", datasetMap);
        //判断医嘱开立者
        Boolean isCreator = false;
        TaskNodeConditionEntity selectedTaskCondition = null;
        for (TaskNodeConditionEntity taskCondition : taskConditions) {
            selectedTaskCondition = taskCondition;
            String formula = taskCondition.getFormula();
            //查询节点对应的节点明细的数据元
            if (StringUtils.isBlank(formula)) {
                logger.info("医嘱：{} 找到无条件执行的路径，结束循环。", inpatorderdataId);
                triggerNextNode = true;     //公式为空直接执行下个节点
                break;
            }
            List<ConditionDetailsDTO> conditionElements = taskConditionElements.stream().filter(conditionDetailsDTO ->
                    conditionDetailsDTO.getConditionId().equals(taskCondition.getConditionId())).collect(Collectors.toList());
            logger.info("查询触发条件医嘱：preTaskNodeId：{} 任务条件: ",conditionElements);
            logger.info("查询触发条件医嘱：preTaskNodeId：{} 优先级--: ",taskCondition.getPriority());
            //匹配引用数据集
            formula = matchQuoteDataSetValue(formula, conditionElements, datasetMap);
            logger.error("获取病人数据formula1：{}", formula);
            //匹配引用模板明细
            formula = matchQuoteTplDetail(formula, conditionElements, taskExecuteEntity.getInpatorderdataId(), taskExecuteEntity.getInpatNum(), taskExecuteEntity, currentDetailId, orderQrCode);
            logger.error("获取病人数据formula2：{}", formula);
            //匹配医嘱文书数据元值
            formula = matchDataValue(formula, conditionElements, dataEntityList);
            logger.error("获取病人数据formula3：{}", formula);
            try {
                triggerNextNode = (Boolean) jse.eval(formula);
            } catch (ScriptException e) {
                logger.info("医嘱：{} 条件JS（{}）执行出错。", inpatorderdataId, formula);
                logger.error("条件JS执行出错", e);
                return ResultGenerator.genFailedResult("任务流执行出错，无法继续。");
            }
            if (triggerNextNode) {
                logger.info("医嘱：{} 找到符合条件的路径，结束循环。", inpatorderdataId);
                break;
            }
        }
//
        if (triggerNextNode) {
            //生成下一个任务节点执行明细以及执行对象
            TaskNodeEntity nextTaskNodeEntity = taskNodeMapper.selectByPrimaryKey(selectedTaskCondition.getTaskNodeId());

            //医嘱开立者
            if (TaskEnum.CREATER.getValue().equals(nextTaskNodeEntity.getExecuteType())) {
                isCreator = true;
            }
            TaskExecuteDetailEntity nextDetailEntityParam = new TaskExecuteDetailEntity();
            nextDetailEntityParam.setTaskExecuteId(taskExecuteEntity.getTaskExecuteId());
            nextDetailEntityParam.setTaskNodeId(selectedTaskCondition.getTaskNodeId());
            List<TaskExecuteDetailEntity> taskExecuteDetailEntities = taskExecuteDetailMapper.queryByEntity(nextDetailEntityParam);


            //创建节点任务执行明细
            TaskExecuteDetailEntity nextDetailEntity = null;
            if (null != taskExecuteDetailEntities && !taskExecuteDetailEntities.isEmpty()) {
                nextDetailEntity = taskExecuteDetailEntities.get(0);
                nextDetailEntity.setBarCode(currentBatchEntity.getBarCode() == null ? currentDetailEntity.getBarCode() : currentBatchEntity.getBarCode());
                nextDetailEntity.setQrCode(currentBatchEntity.getQrCode() == null ? currentDetailEntity.getQrCode() : currentBatchEntity.getQrCode());
            } else {
                nextDetailEntity = new TaskExecuteDetailEntity();
                nextDetailEntity.initAdd();
                nextDetailEntity.setTaskExecuteDetailId(UUIDUtil.randomString());
                nextDetailEntity.setTaskExecuteId(taskExecuteEntity.getTaskExecuteId());
                nextDetailEntity.setTaskNodeId(selectedTaskCondition.getTaskNodeId());
                nextDetailEntity.setSerialNo(taskExecuteMapper.selectSerialByTaskExecuteId(currentDetailEntity.getTaskExecuteId()));
                nextDetailEntity.setStatus(TaskEnum.UNEXECUTED.getValue());
                nextDetailEntity.setBeginDatetime(StringUtils.isBlank(executeBeginTime) ? DateUtil.localDateTime2Date(now) : DateUtil.stringToDate(executeBeginTime));
                nextDetailEntity.setGroupId(groupId);
                nextDetailEntity.setQrCode(currentBatchEntity.getQrCode() == null ? currentDetailEntity.getQrCode() : currentBatchEntity.getQrCode());
                //nextDetailEntity.setBarCode(currentDetailEntity.getBarCode());
                nextDetailEntity.setBarCode(currentBatchEntity.getBarCode() == null ? currentDetailEntity.getBarCode() : currentBatchEntity.getBarCode());
                nextDetailEntity.setParentDetailId(currentDetailId);
            }
            //判断节点batch是否存在
            TaskExecuteBatchEntity nextExecuteBatchEntity = new TaskExecuteBatchEntity();
            nextExecuteBatchEntity.setBatchNo((long) batchNo);
            nextExecuteBatchEntity.setTaskExecuteDetailId(nextDetailEntity.getTaskExecuteDetailId());
            nextExecuteBatchEntity.setTaskNodeId(selectedTaskCondition.getTaskNodeId());
            nextExecuteBatchEntity.setBatchFlag(ConstantEnum.BATCH_FLAG_0.getKey());
            List<TaskExecuteBatchEntity> taskExecuteBatchEntities = taskExecuteBatchMapper.select(nextExecuteBatchEntity);

            // && (null == taskExecuteBatchEntities || taskExecuteBatchEntities.isEmpty())
            if (!TaskEnum.TASK.getValue().equals(nextTaskNodeEntity.getType())) {
                //创建任务节点对应文书
                OrdersFileIndexEntity emrFileIndexEntity = createTaskNodeOrderFileIndex(userId, taskExecuteEntity, selectedTaskCondition.getTaskNodeId(), currentDetailId, "", patientOrders.getInpatNum(), orderQrCode, isSyxs);
                nextDetailEntity.setEmrFileId(emrFileIndexEntity.getEmrFileId());

                TaskExecuteBatchEntity nextBatchEntity = new TaskExecuteBatchEntity();
                nextBatchEntity.initAdd();
                nextBatchEntity.setTaskBatchId(UUIDUtil.randomString());
                nextBatchEntity.setEmrFileId(emrFileIndexEntity.getEmrFileId());
                nextBatchEntity.setStatus(TaskEnum.UNEXECUTED.getValue());
                nextBatchEntity.setInpatorderdataId(inpatorderdataId);
                nextBatchEntity.setSerialNo(currentBatchEntity.getSerialNo() + 1);
                nextBatchEntity.setBatchNo((long) batchNo);
                nextBatchEntity.setTaskExecuteId(nextDetailEntity.getTaskExecuteId());
                nextBatchEntity.setTaskNodeId(nextDetailEntity.getTaskNodeId());
                nextBatchEntity.setBarCode(currentBatchEntity.getBarCode() == null ? currentDetailEntity.getBarCode() : currentBatchEntity.getBarCode());
                nextBatchEntity.setQrCode(currentBatchEntity.getQrCode() == null ? currentDetailEntity.getQrCode() : currentBatchEntity.getQrCode());
                nextBatchEntity.setBatchFlag(ConstantEnum.BATCH_FLAG_0.getKey());
                nextBatchEntity.setTaskExecuteDetailId(nextDetailEntity.getTaskExecuteDetailId());
                nextBatchEntity.setStartDatetime(StringUtils.isBlank(executeBeginTime) ? new Timestamp(DateUtil.localDateTime2Date(now).getTime()) : DateUtil.stringToTimestamp(executeBeginTime));
                taskExecuteBatchMapper.insertSelective(nextBatchEntity);
                if (StringUtils.isNotBlank(nextTaskNodeEntity.getRemindInfo()) && nextTaskNodeEntity.getRemindMinutes() != null) {
                    MessageRemindingEntity remindingEntity = new MessageRemindingEntity();
                    remindingEntity.initAdd();
                    remindingEntity.setRemindingId(UUIDUtil.randomString());
                    remindingEntity.setInpatNum(patientOrders.getInpatNum());
                    remindingEntity.setTaskExecuteBatchId(nextBatchEntity.getTaskBatchId());
                    remindingEntity.setMessageInfo(nextTaskNodeEntity.getRemindInfo());
                    remindingEntity.setSendDate(Timestamp.valueOf(LocalDateTime.now().plusMinutes(nextTaskNodeEntity.getRemindMinutes())));
                    remindingEntity.setSendFlag(TaskEnum.UNEXECUTED.getValue());
                    taskExecuteBatchMapper.insertRemindInfo(remindingEntity);
                }
                TaskExecutorEntity taskExecutorEntity = new TaskExecutorEntity();
                taskExecutorEntity.initAdd();
                taskExecutorEntity.setExecutorId(UUIDUtil.randomString());
                taskExecutorEntity.setTaskExecuteDetailId(nextDetailEntity.getTaskExecuteDetailId());
                if (TaskEnum.DEPT.getValue().equals(nextTaskNodeEntity.getExecuteType()))
                    taskExecutorEntity.setExecutorDeptId(nextTaskNodeEntity.getDeptId());
                else if (TaskEnum.POSITION.getValue().equals(nextTaskNodeEntity.getExecuteType()))
                    taskExecutorEntity.setExecutorPositionId(nextTaskNodeEntity.getPositionId());
                else if (TaskEnum.PERSON.getValue().equals(nextTaskNodeEntity.getExecuteType()))
                    taskExecutorEntity.setExecutorPersonId(nextTaskNodeEntity.getPersonId());
                taskExecutorMapper.insertSelective(taskExecutorEntity);
            }
            if (null == taskExecuteDetailEntities || taskExecuteDetailEntities.isEmpty()) {
                try {
                    taskExecuteDetailMapper.insertSelective(nextDetailEntity);
                } catch (Exception e) {
                    logger.info("医嘱明细插入错误", e);
                }
            }

            //更新医嘱状态为当前任务节点指定状态
            if (StringUtils.isNotBlank(nextTaskNodeEntity.getExecStatus())) {
                logger.info("医嘱：{} 更新医嘱状态：{}", inpatorderdataId, nextTaskNodeEntity.getExecStatus());
                String taskNodeExeStatus = emrFileMapper.getOrderStatusValue(nextTaskNodeEntity.getExecStatus());
                //任务流转发送App消息
                Map<String, String> patientInfo = patientMapper.findPatientById(patientOrders.getInpatNum());
                      if (TaskEnum.TASK.getValue().equals(nextTaskNodeEntity.getType())) {
                    TaskEntity queryTask = new TaskEntity();
                    queryTask.setTaskId(nextTaskNodeEntity.getNodeId());
                    queryTask = taskMapper.selectByPrimaryKey(queryTask);
                    String actionName = "执行到" + queryTask.getTaskName();
                    PatientOrdersEntity finalPatientOrders = patientOrders;
                    fixedThreadPool.execute(() ->
                            sendAppMessage(patientInfo, finalPatientOrders.getOrdersItem(), actionName, OrderStatusEnum.ORDER_TASK_EXECUTE.getValue()));
                } else {
                    NodeEntity queryNode = new NodeEntity();
                    queryNode.setNodeId(nextTaskNodeEntity.getNodeId());
                    queryNode = nodeMapper.selectByPrimaryKey(queryNode);
                    String actionName = "执行到" + queryNode.getNodeName();
                    PatientOrdersEntity finalPatientOrders1 = patientOrders;
                    fixedThreadPool.execute(() ->
                            sendAppMessage(patientInfo, finalPatientOrders1.getOrdersItem(), actionName, OrderStatusEnum.ORDER_TASK_EXECUTE.getValue()));
                }
                patientOrders.setExecStatus(taskNodeExeStatus);
                updateGroupOrders(patientOrders);
            }
            //判断该执行节点是否触发子任务
            if (TaskEnum.TASK.getValue().equals(nextTaskNodeEntity.getType())) {
                logger.info("医嘱：{} 生成子任务执行。", inpatorderdataId);
                Condition subCondition = new Condition(TaskNodeEntity.class);
                subCondition.createCriteria().andEqualTo("taskId", nextTaskNodeEntity.getNodeId())
                        .andEqualTo("headFlag", "1");
                TaskNodeEntity subTaskNodeEntity = taskNodeMapper.selectByCondition(subCondition).get(0);
                //创建任务节点对应文书
                OrdersFileIndexEntity emrFileIndexEntity = createTaskNodeOrderFileIndex(userId, taskExecuteEntity, subTaskNodeEntity.getTaskNodeId(), "", "", patientOrders.getInpatNum(), orderQrCode, "");

                //创建子任务执行
                TaskExecuteDetailEntity taskExecuteDetailEntity = null;
                if (null == taskExecuteDetailEntities || taskExecuteDetailEntities.isEmpty()) {
                    taskExecuteDetailEntity = createTaskExecute(nextDetailEntity.getTaskExecuteDetailId(), batchNo, taskExecuteEntity.getInpatorderdataId(), TaskEnum.UNEXECUTED.getValue(), subTaskNodeEntity, emrFileIndexEntity, now, currentBatchEntity.getQrCode() == null ? currentDetailEntity.getQrCode() : currentBatchEntity.getQrCode(), currentBatchEntity.getBarCode() == null ? currentDetailEntity.getBarCode() : currentBatchEntity.getBarCode());
                } else {
                    taskExecuteDetailEntity = taskExecuteDetailEntities.get(0);
                    TaskExecuteDetailEntity p1 = new TaskExecuteDetailEntity();
                    p1.setTaskExecuteId(taskExecuteDetailEntity.getTaskExecuteDetailId());
                    List<TaskExecuteDetailEntity> subDetails = taskExecuteDetailMapper.queryByEntity(p1);
                    subDetails = subDetails.stream().filter(taskExecuteDetailEntity1 -> StringUtils.isBlank(taskExecuteDetailEntity1.getParentDetailId())).collect(Collectors.toList());
                    if (null != subDetails && !subDetails.isEmpty()) {
                        if (TaskEnum.STRATEGY_ONE.getValue().equals(nextTaskNodeEntity.getStrategy())) {
                            //根据子任务创建人物对应频次

//                            createInjections2(subDetails.get(0), patientOrders, orderQrCode, subTaskNodeEntity.getTaskId(), batchNo, userId, emrFileIndexEntity);
                        }
                        return createNextTaskNode(subDetails.get(0).getTaskExecuteDetailId(), batchNo, userId, "", "", "", orderQrCode,null);//, false
                    }
                }
                if (TaskEnum.STRATEGY_ONE.getValue().equals(nextTaskNodeEntity.getStrategy())) {
                    //根据子任务创建人物对应频次
//                    int finalBatchNo = batchNo;
//                    TaskExecuteDetailEntity finalTaskExecuteDetailEntity = taskExecuteDetailEntity;
//                    String finalOrderQrCode = orderQrCode;
//                    String finalUserId = userId;
//                    fixedThreadPool.execute(() -> createInjections2(finalTaskExecuteDetailEntity, patientOrders, finalOrderQrCode, subTaskNodeEntity.getTaskId(), finalBatchNo, finalUserId, emrFileIndexEntity));
                }
            }
            if (TaskEnum.AUTO.getValue().equals(nextTaskNodeEntity.getExecuteType())) {
                logger.info("医嘱：{} 自动结束节点，开始创建下一节点。", inpatorderdataId);
                return createNextTaskNode(nextDetailEntity.getTaskExecuteDetailId(), batchNo, userId, groupId, "", "", orderQrCode,null);//, false
            } else {
                logger.info("医嘱：{} 非自动结束节点，结束处理。", inpatorderdataId);
//                if (sendMsgFlag && isCreator) {
//                    sendQueryNotify(userId);
//                }
                return ResultGenerator.genOkResult();
            }
        }

        //所有的下个节点条件都不符合，则结束任务执行
        TaskExecuteDetailEntity parentTaskDetail = taskExecuteDetailMapper.selectByPrimaryKey(taskExecuteEntity.getTaskExecuteId());
        if (parentTaskDetail == null) { //护理
            int unExeTaskExecuteCount = patientOrderMapper.countUnExeTaskExecuteDetail(taskExecuteEntity.getInpatorderdataId(), taskExecuteEntity.getTaskId());
            if (unExeTaskExecuteCount == 0) {   //所有批次的输液执行任务明细都执行完，结束医嘱父任务
                Condition parentTaskExeCondition = new Condition(TaskExecuteEntity.class);
                parentTaskExeCondition.createCriteria().andEqualTo("inpatorderdataId", taskExecuteEntity.getInpatorderdataId())
                        .andNotEqualTo("taskId", taskExecuteEntity.getTaskId());
                List<TaskExecuteEntity> parentTaskExecuteList = taskExecuteMapper.selectByCondition(parentTaskExeCondition);
                if (!parentTaskExecuteList.isEmpty()) {     //输液父任务
                    TaskExecuteEntity parentTaskExecute = parentTaskExecuteList.get(0);
                    parentTaskExecute.setEndDatetime(DateUtil.localDateTime2Date(now));
                    taskExecuteMapper.updateByPrimaryKeySelective(parentTaskExecute);
                    Condition parentTaskExeDetailCondition = new Condition(TaskExecuteDetailEntity.class);
                    parentTaskExeDetailCondition.createCriteria().andEqualTo("taskExecuteId", parentTaskExecute.getTaskExecuteId())
                            .andEqualTo("status", TaskEnum.UNEXECUTED.getValue());
                    TaskExecuteDetailEntity parentTaskUnExeDetail = new TaskExecuteDetailEntity();
                    parentTaskUnExeDetail.setStatus(TaskEnum.EXECUTED.getValue());
                    parentTaskUnExeDetail.setEndDatetime(new Date());
                    taskExecuteDetailMapper.updateByConditionSelective(parentTaskUnExeDetail, parentTaskExeDetailCondition);
                }
            }
        }
        //判断是否存在父任务，存在则更新父任务结束时间
        if (parentTaskDetail != null) {
            parentTaskDetail.setStatus(TaskEnum.EXECUTED.getValue());
            parentTaskDetail.setEndDatetime(new Date());
            taskExecuteDetailMapper.updateByPrimaryKey(parentTaskDetail);
//             TaskExecuteBatchEntity parentBatchEntity = taskExecuteBatchMapper.getLastBatchEntity(inpatorderdataId, batchNo);
//            parentBatchEntity.setStopDatetime(DateUtil.localDateTime2Date(now));
//            parentBatchEntity.setExecutePersonId(userId);
//            parentBatchEntity.setStatus(TaskEnum.EXECUTED.getValue());
//            taskExecuteBatchMapper.updateByPrimaryKeySelective(parentBatchEntity);
            TaskExecuteEntity parentTaskExecute = new TaskExecuteEntity();
            parentTaskExecute.setTaskExecuteId(parentTaskDetail.getTaskExecuteId());
            parentTaskExecute.setEndDatetime(DateUtil.localDateTime2Date(now));
            taskExecuteMapper.updateByPrimaryKeySelective(parentTaskExecute);
        }
        taskExecuteEntity.setEndDatetime(DateUtil.localDateTime2Date(now));
        taskExecuteMapper.updateByPrimaryKeySelective(taskExecuteEntity);
//        if (sendMsgFlag && isCreator) {
//            sendQueryNotify(userId);
//
//        }
        return ResultGenerator.genOkResult();
    }

    public OrdersFileIndexEntity createTaskNodeOrderFileIndex(String userId, TaskExecuteEntity taskExecuteEntity, String taskNodeId, String taskExeDetailId, String tplId, String inpatNum, String qrCode, String isSyxs) {

        logger.info("创建任务节点对应文书,用户id{},任务执行id{},任务节点id{}", userId, taskExecuteEntity.getTaskExecuteId(), taskNodeId);
        Map<String, String> template;
        if (StringUtils.isNotEmpty(tplId)) {
            template = JSONObject.parseObject(JSONObject.toJSONString(emrTemplateMapper.selectByPrimaryKey(tplId)), Map.class);
        } else {
            template = nodeMapper.getTplByTaskNode(taskNodeId);
        }
        OrdersFileIndexEntity emrFileIndex = new OrdersFileIndexEntity();
        Timestamp currentTime = new Timestamp(System.currentTimeMillis());
        Map<String, String> currentUser = patientOrderMapper.getUser(userId);
        Map<String, String> patientInfo = patientMapper.getPatientInfo(inpatNum);
        String userName = currentUser.get("userName");
        if (StringUtils.isBlank(userName))
            userName = "无名";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
        String emrFileName = userName + "—" + sdf.format(new Date(currentTime.getTime()));
        emrFileIndex.setEmrFileName(emrFileName);
        emrFileIndex.setHospitalId(taskExecuteEntity.getHospitalId());
        emrFileIndex.setDataVersion(1);
        emrFileIndex.setOutpatNum("0");
        emrFileIndex.setDelFlag(StateEnum.EMR_UNDEL.getValue());
        emrFileIndex.setInpatNum(inpatNum);
        emrFileIndex.setDoctorId(currentUser.get("userId"));
        emrFileIndex.setDeptId(patientInfo.get("deptId"));
        emrFileIndex.setWardDeptId(patientInfo.get("wardDeptId"));
        emrFileIndex.setGmtCreate(currentTime);
        emrFileIndex.setGmtModify(currentTime);
        if (template != null) {
            emrFileIndex.setEmrFileId(UUIDUtil.randomString());
            emrFileIndex.setTplId(template.get("tplId"));
        } else {
            return emrFileIndex;
        }
        emrFileIndexEntityMapper.insertSelective(emrFileIndex);
        List<CompletableFuture<Tuple2<String, JSONObject>>> datasetFutures = getDatasetMap(emrFileIndex.getTplId(), emrFileIndex.getInpatNum(), "", "", template.get("emrType"));
        currentUser.put("deptId", patientInfo.get("deptId"));
        currentUser.put("deptName", patientInfo.get("deptName"));
        List<EmrFileData> dataList = createEmrFileData(emrFileIndex, datasetFutures, currentUser, taskExecuteEntity, taskExeDetailId, null, null, qrCode, isSyxs);
        //技术职称
        String userGroupEleId = patientOrderMapper.getSysElementIdByVarCode("order_jszc");
        //是否送检
        String sfsjEleId = patientOrderMapper.getSysElementIdByVarCode("order_sfsj");
        //是否感染疾病科会诊
        String sfgrjbhzEleId = patientOrderMapper.getSysElementIdByVarCode(ConstantEnum.VAR_CODE_GRKHZ.getKey());
        //费别
        String feeTypeEleId = patientOrderMapper.getSysElementIdByVarCode(ConstantEnum.VAR_CODE_FEE_TYPE.getKey());
        //合理用药审批tplId
        String hlyyTplId = patientOrderMapper.getSysElementIdByVarCode(ConstantEnum.VAR_CODE_TPL_ID_HLYYSP.getKey());
        //医嘱id
        String inpatOrderDataId = taskExecuteEntity.getInpatorderdataId();
        //药品信息
        Map<String, String> drugInfo = new HashMap<>();

        if (StringUtils.isNotBlank(inpatOrderDataId)) {
            drugInfo = patientOrderMapper.getOrderDrugInfo(inpatOrderDataId);

        }

        for (EmrFileData emrFileData : dataList) {

            OrdersFileIndexDataEntity fileIndexDataEntity = emrFileData.getFileIndexDataEntity();
            if (Objects.equals(fileIndexDataEntity.getElementId(), userGroupEleId)) {  //技术职称填入当前用户职称
                fileIndexDataEntity.setDataValue(currentUser.get("groupName"));
            }
            //药品名称
            if (ConstantEnum.VAR_CODE_CFYP.getKey().equals(emrFileData.getElement().getVarCode()) && !CollectionUtils.isEmpty(drugInfo)) {
                fileIndexDataEntity.setDataValue(drugInfo.get("DRUG_NAME"));
            }
            //规格
            if (ConstantEnum.VAR_CODE_GUIGE.getKey().equals(emrFileData.getElement().getVarCode()) && !CollectionUtils.isEmpty(drugInfo)) {
                fileIndexDataEntity.setDataValue(drugInfo.get("DRUG_SPEC"));
            }
            //用药途径
            if (ConstantEnum.VAR_CODE_YYTJ.getKey().equals(emrFileData.getElement().getVarCode()) && !CollectionUtils.isEmpty(drugInfo)) {
                fileIndexDataEntity.setDataValue(drugInfo.get("administration"));
            }
            if (Objects.equals(fileIndexDataEntity.getElementId(), sfsjEleId)) {  //抗菌药物会诊是否送检

                int i = patientOrderMapper.countPathogenLabReport(taskExecuteEntity.getInpatNum());
                if (i > 0) {
                    fileIndexDataEntity.setDataCode("0");
                }
            }
            //判断是否有感染疾病科会诊记录
            if (Objects.equals(fileIndexDataEntity.getElementId(), sfgrjbhzEleId)) {  //抗菌药物会诊是否送检

                List<String> deptIds = new ArrayList<>();
                deptIds.add(ConstantEnum.DEPT_CODE_203503.getKey());
                int i = patientOrderMapper.queryHzDept(ConstantEnum.VAR_CODE_HZDEPT.getKey(), patientInfo.get("inpatNum"), deptIds);
                if (i > 0) {
                    fileIndexDataEntity.setDataCode("0");
                }
            }
            //费别
            if (Objects.equals(fileIndexDataEntity.getElementId(), feeTypeEleId) && StringUtils.isNotBlank(inpatNum)) {
                try {
                    JSONObject result10001 = his10001(inpatNum);
                    if (null != result10001 && !result10001.isEmpty()) {
                        String ybType = (String) JSONArray.parseArray(result10001.getString("data"), Map.class).get(0).get("CHARGE_TYPE");
                        if (StringUtils.isNotBlank(ybType)) {
                            fileIndexDataEntity.setDataValue(ybType);
                        }
                    }
                } catch (Exception e) {
                    logger.info("费别调用失败:{}", e);
                }
            }
            //合理用药审批设置默认理由
            if (StringUtils.isNotBlank(hlyyTplId) && hlyyTplId.equals(template.get("tplId")) && ConstantEnum.VAR_CODE_SP_SQLY.getKey().equals(emrFileData.getElement().getVarCode())) {
                //处方
                if (ConstantEnum.TASK_PRESC.getKey().equals(taskExecuteEntity.getDataType())) {
                    List<DrugRationalUse> drugRationalUseList = drugRationalUseMapper.selectPrescByParams(taskExecuteEntity.getInpatorderdataId(), ConstantEnum.ZH_TSJKJYW.getKey());
                    if (null != drugRationalUseList && !drugRationalUseList.isEmpty()) {
                        fileIndexDataEntity.setDataValue(drugRationalUseList.stream().map(DrugRationalUse::getCtrlName).collect(Collectors.joining(",")));
                    }
                }
                //医嘱
                else if (ConstantEnum.TASK_ORDER.getKey().equals(taskExecuteEntity.getDataType())) {
                    List<DrugRationalUse> drugRationalUseList = drugRationalUseMapper.selectByParams(taskExecuteEntity.getInpatorderdataId(), ConstantEnum.ZH_TSJKJYW.getKey());
                    if (null != drugRationalUseList && !drugRationalUseList.isEmpty()) {
                        fileIndexDataEntity.setDataValue(drugRationalUseList.stream().map(DrugRationalUse::getCtrlName).collect(Collectors.joining(",")));
                    }
                }
            }
        }
        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
        Map<String, Object> params = new HashMap<>();
        params.put("fileIndex", emrFileIndex);
        dataList.stream().map(data -> data.getFileIndexDataEntity()).forEach(dataEntity -> {
            params.put("dataEntity", dataEntity);
            session.insert("com.haoze.nurseapp.dao.EmrFileMapper.insertDataList", params);
        });
        session.flushStatements();
        session.close();
        return emrFileIndex;
    }

    private List<CompletableFuture<Tuple2<String, JSONObject>>> getDatasetMap(String tplId, String inpatNum, String reqNum, String serialNo, String emrType) {
        List<Map<String, String>> datasetList = emrFileMapper.getDatasetListNew(tplId);
        List<CompletableFuture<Tuple2<String, JSONObject>>> futures = datasetList.stream().map(dataset -> {
            return CompletableFuture.supplyAsync(() -> {
                long t1 = System.currentTimeMillis();
                String datasetId = dataset.get("DATASET_ID");
                String url = dataset.get("READ_SERVICE");
                if (StringUtils.isBlank(url)) {
                    return null;
                }
                Map<String, String> params = new HashMap<String, String>();
                params.put("DATASET_ID", datasetId);
                params.put("inpatNum", inpatNum);
                if (StringUtils.isNotBlank(reqNum)) {
                    params.put("reqNum", reqNum);
                }
                if (StringUtils.isNotBlank(serialNo)) {
                    params.put("serialNo", serialNo);
                }
                params.put("emrType", emrType);
                Result result = dataSetValueCommonService.commonDataSetValue(params);
                long t2 = System.currentTimeMillis();
                logger.info("查询第三方接口 {} 数据耗时：{} ms", url, t2 - t1);
                if (result.getCode() == 200) {
                    JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
                    return Tuples.of(datasetId, data);
                } else {
                    return null;
                }
            });
        }).collect(Collectors.toList());
        return futures;
    }

    private JSONObject his10001(String inpatNum) {
        Map<String, Object> param = new HashMap<>();
        param.put("as_patientId", inpatNum.replace("-1", ""));
        param.put("operationID", ConstantEnum.HIS_EMR_NEW_10001.getKey());
        param.put("al_visitId", "1");
        param.put("al_doctor_type", "");
        return HttpClientUtil.sendPost(ConstantEnum.HIS_EMR_NEW_URL.getKey(), param);
    }

    private List<EmrFileData> createEmrFileData(OrdersFileIndexEntity emrFileIndex, List<CompletableFuture<Tuple2<String, JSONObject>>> datasetFeatures,
                                                Map<String, String> currentUser, TaskExecuteEntity taskExecuteEntity, String taskExeDetailId, String preDataCode, String preDataValue, String qrCode, String isSyxs) {
        long t1 = System.currentTimeMillis();
        List<Map<String, Object>> list = patientOrderMapper.createEmrFileData(emrFileIndex.getTplId());
        long t2 = System.currentTimeMillis();
        logger.info("{} 模板{}条查询时间：{} ms", emrFileIndex.getTplId(), list.size(), t2 - t1);
        List<EmrFileData> emrFileDataList = convertData(list, currentUser, preDataCode, preDataValue);
        Map<String, Map<String, Object>> datasetMap = new HashMap<>();
        try {
            CompletableFuture.allOf(datasetFeatures.toArray(new CompletableFuture[datasetFeatures.size()])).thenApply(v -> {
                return datasetFeatures.stream().map(datasetFeature -> datasetFeature.join())
                        .collect(Collectors.toList());
            }).get().stream().filter(tuple2 -> tuple2 != null).forEach(tuple2 -> {
                datasetMap.put(tuple2.getT1(), tuple2.getT2());
            });
        } catch (Exception e) {
            logger.error("查询第三方接口出现错误。", e);
        }
        int orignialSize = emrFileDataList.size();
        List<OrdersFileIndexDataEntity> dataEntities = new CopyOnWriteArrayList<>();
        for (int i = 0; i < orignialSize; i++) {
            EmrFileData emrFileData = emrFileDataList.get(i);
            OrdersFileIndexDataEntity dataEntity = emrFileData.getFileIndexDataEntity();
            String oldId = dataEntity.getFileIndexDataId();
            String newId = UUIDUtil.randomString();
            dataEntity.setFileIndexDataId(newId);
            Element element = emrFileData.getElement();

            // 引用数据集
            if (StringUtils.isNotBlank(dataEntity.getQuoteDatasetId()) && StringUtils.isNotBlank(dataEntity.getQuoteElementId())) {
                updateQuoteDatasetValue(datasetMap, emrFileData, true);
            }
            // 补充全部勾选项
            if (element.getElementPropertyFormat() != null && element.getElementPropertyFormat().indexOf("\"formatValue\":\"2\"") > -1) {
                element.setSelections(emrFileMapper.getAllSelections(element.getId()));
            }

            // 引用其他病历 新版本
            if (StringUtils.isNotBlank(dataEntity.getQuoteTplDetailId()) && dataEntity.getQuoteTplDetailId().startsWith("[[")) {
                JSONArray priorityArray = JSONArray.parseArray(dataEntity.getQuoteTplDetailId());
                for (int index = 0; index < priorityArray.size(); index++) {
                    JSONArray totalArray = (JSONArray) priorityArray.get(index);
                    if (index == 0 && StringUtils.isNotEmpty(isSyxs)) {
                        JSONObject jsonObject = (JSONObject) totalArray.get(0);
                        //当前节点及其上一流程节点为输液巡视时，引用输液巡视内容，忽略新增输液 -> 其他标签 内容
                        if ("其他_标签(新增输液)".equals(jsonObject.getString("text"))) {
                            continue;
                        } else if ("肠内营养_标签(肠内营养输注)".equals(jsonObject.getString("text"))) {//肠内营养同样处理
                            continue;
                        }
                    }
                    boolean isFound = totalArray.stream().map(parallelingObj -> {
                        JSONObject quoteRule = (JSONObject) parallelingObj;
                        String quoteCtlId = quoteRule.getString("quoteCtlId");
                        if (StringUtils.isEmpty(quoteCtlId) && taskExecuteEntity == null) {
                            logger.info("缺少目录和医嘱，无法引用。");
                            return false;
                        }
                        List<OrdersFileIndexDataEntity> refDataList;
                        if (StateEnum.CATALOG_ORDERS.getValue().equals(quoteRule.getString("quoteNodeType"))) {
                            if (taskExecuteEntity != null) { // 引用本次医嘱
                                Map<String, String> fileDataByOrder = emrFileMapper.getFileDataByOrder(taskExecuteEntity.getInpatorderdataId());
                                String inpatorderdataId = taskExecuteEntity.getInpatorderdataId();
                                if (StringUtils.isNotBlank(fileDataByOrder.get("fileIndexDataId"))) {
                                    inpatorderdataId = fileDataByOrder.get("fileIndexDataId");
                                }
                                refDataList = emrFileMapper.queryRefOrderData(quoteRule.getString("quoteId"), inpatorderdataId, emrFileIndex.getInpatNum(),
                                        quoteRule.getString("quoteAll"), quoteRule.getString("isDesc"), fileDataByOrder.get("emrFileId"), fileDataByOrder.get("elementId"));
                            } else { // 开医嘱时引用上次医嘱
                                refDataList = emrFileMapper.queryRefLastOrderData(quoteRule.getString("quoteId"), quoteCtlId, emrFileIndex.getInpatNum());
                            }
                        } else if (StateEnum.CATALOG_TASKS.getValue().equals(quoteRule.getString("quoteNodeType"))) {
                            refDataList = emrFileMapper.queryRefBatchData(quoteRule.getString("quoteId"), quoteCtlId, quoteRule.getString("quoteAll"), quoteRule.getString("isDesc"), taskExecuteEntity.getTaskExecuteId(), qrCode);
                            //如果当前数据元id是滴速或者剩余量则取最新值
                            if (null != ElementVarForSpecialEnum.getId(emrFileMapper.getVarCodeByElementId(element.getId()))) {
                                dataEntities.addAll(refDataList);
                            }
                        } else {
                            refDataList = emrFileMapper.queryRefData(quoteRule.getString("quoteId"), quoteCtlId, emrFileIndex.getInpatNum(), quoteRule.getString("quoteAll"), quoteRule.getString("isDesc"));
                        }
                        if (refDataList.isEmpty()) { // 引用节点已不存在 忽略
                            return false;
                        }
                        return IntStream.range(0, refDataList.size()).mapToObj(idx -> {
                            OrdersFileIndexDataEntity refData = refDataList.get(idx);
                            if ("Y".equals(quoteRule.getString("oneToOne"))) { // 点对点引用
                                if (StringUtils.isEmpty(refData.getDataValue())) {
                                    return false;
                                }
                                dataEntity.setDataValue(refData.getDataValue());
                                dataEntity.setDataCode(refData.getDataCode());
                                if (!CollectionUtils.isEmpty(dataEntities)) {
                                    OrdersFileIndexDataEntity fileIndexDataEntity = dataEntities.parallelStream().sorted(Comparator.comparing(OrdersFileIndexDataEntity::getCreateTime).reversed()).collect(Collectors.toList()).get(0);
                                    dataEntity.setDataValue(fileIndexDataEntity.getDataValue());
                                    dataEntity.setDataCode(fileIndexDataEntity.getDataCode());
                                }
                                return true; // 有数据 才算找到
                            }
                            // 引用下级节点
                            long t3 = System.currentTimeMillis();
                            // 优先在病历中找
                            List<EmrFileData> refList = getEmrFileData(refData.getEmrFileId(), refData.getFileIndexDataId(), currentUser);
                            if (refList.isEmpty()) { // 尝试在医嘱文书中找
                                refList = getOrderFileData(refData.getEmrFileId(), refData.getFileIndexDataId(), currentUser);
                            }
                            long t4 = System.currentTimeMillis();
                            logger.info("被引用病历{}条查询时间：{} ms", refList.size(), t4 - t3);
                            if (refList.isEmpty()) { // 无子节点 也算找到了
                                return true;
                            }
                            String type = quoteRule.getString("type");
                            if ("2".equals(type)) { // 医疗术语 引用节点本身也添加进去
                                EmrFileData tempData = new EmrFileData();
                                Element tempElement = new Element();
                                tempElement.setType("20");
                                tempData.setElement(tempElement);
                                tempData.setFileIndexDataEntity(refData);
                                refList.add(0, tempData);
                            }
                            for (int j = 0; j < refList.size(); j++) {
                                EmrFileData subRefData = refList.get(j);
                                subRefData.setFirstQuote(true); // 标记为第一次引用 提示前端不要进行自引用修改
                                OrdersFileIndexDataEntity refDataEntity = subRefData.getFileIndexDataEntity();
                                if ("2".equals(type)) {
                                    if (refDataEntity == refData) { // 医疗术语本身
                                        refDataEntity.setParentFileIndexDataId(newId);
                                    }
                                } else {
                                    if (refDataEntity.getParentFileIndexDataId().equals(refData.getFileIndexDataId())) {
                                        refDataEntity.setParentFileIndexDataId(newId);
                                    }
                                }

                                String subOldId = refDataEntity.getFileIndexDataId();
                                String subNewId = UUIDUtil.randomString();
                                refDataEntity.setFileIndexDataId(subNewId);
                                refDataEntity.setCreateTime(dataEntity.getCreateTime());
                                refDataEntity.setModifyTime(dataEntity.getModifyTime());
                                try {
                                    String elementProperty = refDataEntity.getElementProperty();
                                    JSONObject jsonObject = JSONObject.parseObject(elementProperty);
                                    jsonObject.put("printNewLine", "1");
                                    jsonObject.put("childPrintNewLine", "1");
                                    jsonObject.put("printAlign", "0");
                                    jsonObject.put("printFontBold", "1");
                                    jsonObject.put("printSplitLine", "1");
                                    jsonObject.put("childrenPrintAlign", "0");
                                    jsonObject.put("selfPrintAlign", "0");
                                    if (idx != 0 && j == 0) { // 第一项增加一个换行符号
                                        jsonObject.put("newLine", "0");
                                        jsonObject.put("printNewLine", "0");
                                    }
                                    refDataEntity.setElementProperty(jsonObject.toJSONString());
                                } catch (Exception e) {
                                    logger.error("重置elementProperty出错。", e);
                                }
                                for (int k = j; k < refList.size(); k++) {
                                    EmrFileData subNextData = refList.get(k);
                                    OrdersFileIndexDataEntity subNextDataEntity = subNextData.getFileIndexDataEntity();
                                    if (subOldId.equals(subNextDataEntity.getParentFileIndexDataId())) {
                                        subNextDataEntity.setParentFileIndexDataId(subNewId);
                                    }
                                }
                            }

                            emrFileDataList.addAll(refList);
                            return true;
                        }).reduce(false, (accumulatorBoolean, nextBoolean) -> accumulatorBoolean || nextBoolean);
                    }).reduce(false, (accumulatorBoolean, nextBoolean) -> accumulatorBoolean || nextBoolean);
                    // 如果已经引用到数据 终止循环
                    if (isFound && null == ElementVarForSpecialEnum.getId(emrFileMapper.getVarCodeByElementId(element.getId())))
                        break;
                }
            }
            // 补充父级ID
            for (int j = i + 1; j < orignialSize; j++) {
                EmrFileData nextData = emrFileDataList.get(j);
                if (oldId.equals(nextData.getFileIndexDataEntity().getParentFileIndexDataId())) {
                    nextData.getFileIndexDataEntity().setParentFileIndexDataId(newId);
                }
            }
        }
        return emrFileDataList.parallelStream().filter(emrFileData -> {
            Element element = emrFileData.getElement();
            if ("手术名称".equals(element.getName()) && "手术名称".equals(emrFileData.getFileIndexDataEntity().getDataValue())) {
                emrFileData.getFileIndexDataEntity().setDataValue("-");
            }
            //日期类型
            if (ELEMENT_TYPE_THREE.equals(element.getType())) {
                String time = emrFileData.getFileIndexDataEntity().getDataValue();
                if (StringUtils.isNotBlank(time)) {
                    Date dateStr = null;
                    String dataValue = time;
                    try {
                        if (StringUtils.isNotBlank(element.getFormat())) {//redis中未存elementPropertyFormat 直接取format
                            JSONObject format = JSONObject.parseObject(element.getFormat());
                            String formatValue = format.getString("formatValue");
                            if (StringUtils.isNotBlank(formatValue)) {
                                if ("HH:mm".equals(formatValue)) {
                                    if (time.length() > 11) { //引用其他病历存在 HH:mm 值
                                        dataValue = time.substring(11);
                                    } else {
                                        dataValue = time;
                                    }
                                } else {
                                    SimpleDateFormat sdf = new SimpleDateFormat(formatValue);//格式取数据元定义格式
                                    dateStr = sdf.parse(time);
                                    dataValue = sdf.format(dateStr);
                                }
                            }
                        }
                    } catch (Exception e) {
                        dataValue = time;
                        logger.error("日期数据转换出错。", e);
                    }
                    emrFileData.getFileIndexDataEntity().setDataValue(dataValue);
                }
            }
            return true;
        }).collect(Collectors.toList());
    }

    /**
     * 生成任务执行
     *
     * @param taskExecuteId    任务执行id
     * @param inpatorderdataId 医嘱id
     * @param emrFileIndex     文书
     * @param orderQrCode
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public TaskExecuteDetailEntity createTaskExecute(String taskExecuteId, long batchNo, String inpatorderdataId, String execeted, TaskNodeEntity taskNodeEntity,
                                                     OrdersFileIndexEntity emrFileIndex, LocalDateTime localDateTime, String orderQrCode, String barCode) {
//        localDateTime = localDateTime.plusSeconds(1);
        Date date = DateUtil.localDateTime2Date(localDateTime);
        if (taskNodeEntity == null) {
            taskNodeEntity = patientOrderMapper.getOrderBeginTaskNode();
            if (taskNodeEntity == null) {
                logger.info("医嘱：{] 无法找到任务起始的节点", inpatorderdataId);
                throw new ServiceException("无法找到任务起始的节点。");
            }
        }
        //新增任务执行
        TaskExecuteEntity taskExecuteEntity = new TaskExecuteEntity();
        taskExecuteEntity.initAdd();
        taskExecuteEntity.setTaskExecuteId(taskExecuteId);
        taskExecuteEntity.setOutpatNum(emrFileIndex.getOutpatNum());
        taskExecuteEntity.setInpatNum(emrFileIndex.getInpatNum());
        taskExecuteEntity.setDeptId(emrFileIndex.getDeptId());
        taskExecuteEntity.setInpatorderdataId(inpatorderdataId);
        taskExecuteEntity.setWardDeptId(emrFileIndex.getWardDeptId());
        taskExecuteEntity.setTaskId(taskNodeEntity.getTaskId());
        taskExecuteEntity.setBeginDatetime(date);
        taskExecuteEntity.setDataType(ConstantEnum.TASK_ORDER.getKey());
        taskExecuteMapper.insertSelective(taskExecuteEntity);
        //新增任务执行起始节点明细
        TaskExecuteDetailEntity startDetailEntity = new TaskExecuteDetailEntity();
        startDetailEntity.initAdd();
        startDetailEntity.setTaskExecuteDetailId(UUIDUtil.randomString());
        startDetailEntity.setTaskExecuteId(taskExecuteEntity.getTaskExecuteId());
        startDetailEntity.setTaskNodeId(taskNodeEntity.getTaskNodeId());
        startDetailEntity.setSerialNo(1);
        startDetailEntity.setBeginDatetime(date);
//        startDetailEntity.setEndDatetime(date);
        startDetailEntity.setEmrFileId(emrFileIndex.getEmrFileId());
        startDetailEntity.setStatus(execeted);
        startDetailEntity.setBarCode(barCode);
        startDetailEntity.setQrCode(orderQrCode);
        taskExecuteDetailMapper.insertSelective(startDetailEntity);
        TaskExecuteBatchEntity batchEntity = new TaskExecuteBatchEntity();
        batchEntity.initAdd();
        batchEntity.setTaskBatchId(UUIDUtil.randomString());
        batchEntity.setEmrFileId(emrFileIndex.getEmrFileId());
        batchEntity.setStatus(execeted);
        batchEntity.setQrCode(StringUtils.isEmpty(orderQrCode) ? inpatorderdataId : orderQrCode);
        batchEntity.setBarCode(barCode);
        batchEntity.setInpatorderdataId(inpatorderdataId);
        batchEntity.setBatchFlag(ConstantEnum.BATCH_FLAG_0.getKey());
        int serialNo = taskExecuteBatchMapper.getMaxSerialNo(inpatorderdataId, batchNo);
        batchEntity.setSerialNo(serialNo);
        batchEntity.setBatchNo((long) batchNo);
        batchEntity.setTaskNodeId(taskNodeEntity.getTaskNodeId());
        batchEntity.setTaskExecuteId(taskExecuteEntity.getTaskExecuteId());
        batchEntity.setTaskExecuteDetailId(startDetailEntity.getTaskExecuteDetailId());
        batchEntity.setStartDatetime(new Timestamp(date.getTime()));
        taskExecuteBatchMapper.insertSelective(batchEntity);

        //生成任务执行对象
        TaskExecutorEntity taskExecutorEntity = new TaskExecutorEntity();
        taskExecutorEntity.initAdd();
        taskExecutorEntity.setExecutorId(UUIDUtil.randomString());
        taskExecutorEntity.setTaskExecuteDetailId(startDetailEntity.getTaskExecuteDetailId());
        if (TaskEnum.DEPT.getValue().equals(taskNodeEntity.getExecuteType()))
            taskExecutorEntity.setExecutorDeptId(taskNodeEntity.getDeptId());
        else if (TaskEnum.POSITION.getValue().equals(taskNodeEntity.getExecuteType()))
            taskExecutorEntity.setExecutorPositionId(taskNodeEntity.getPositionId());
        else if (TaskEnum.PERSON.getValue().equals(taskNodeEntity.getExecuteType()))
            taskExecutorEntity.setExecutorPersonId(taskNodeEntity.getPersonId());
        taskExecutorMapper.insertSelective(taskExecutorEntity);
        //更新医嘱状态为当前任务节点指定状态
        if (StringUtils.isNotBlank(taskNodeEntity.getExecStatus())) {
            logger.info("医嘱：{} 更新医嘱状态：{}", inpatorderdataId, taskNodeEntity.getExecStatus());
            PatientOrdersEntity patientOrdersEntity = patientOrderMapper.selectByPrimaryKey(taskExecuteEntity.getInpatorderdataId());
            String taskNodeExeStatus = emrFileMapper.getOrderStatusValue(taskNodeEntity.getExecStatus());
            patientOrdersEntity.setExecStatus(taskNodeExeStatus);
            patientOrderMapper.updateByPrimaryKeySelective(patientOrdersEntity);
        }
        if (TaskEnum.AUTO.getValue().equals(taskNodeEntity.getExecuteType())) {
            logger.info("医嘱：{} 自动结束节点，开始创建下一节点。", inpatorderdataId);
            createNextTaskNode(startDetailEntity.getTaskExecuteDetailId(), batchNo, emrFileIndex.getDoctorId(), "", "", "", orderQrCode,null);
        }
        return startDetailEntity;
    }

    @Override
    public void createNextTaskNodeList(List<Map<String, Object>> taskExecuteDetailEntityMap, String msgContent) {
        for (int i = 0; i < taskExecuteDetailEntityMap.size(); i++) {
            Map<String, Object> map = taskExecuteDetailEntityMap.get(i);
            TaskExecuteBatchEntity taskExecuteBatchEntity = JSONObject.parseObject(JSONObject.toJSONString(map.get("taskExecuteDetailEntity")), TaskExecuteBatchEntity.class);
            String userId = (String) map.get("userId");
            TaskExecuteDetailEntity taskExecuteDetailEntity = taskExecuteDetailMapper.selectByPrimaryKey(taskExecuteBatchEntity.getTaskExecuteDetailId());
            createNextTaskNode(taskExecuteBatchEntity.getTaskExecuteDetailId(), taskExecuteBatchEntity.getBatchNo(), userId, taskExecuteDetailEntity.getGroupId(), msgContent, "", taskExecuteBatchEntity.getQrCode(),taskExecuteBatchEntity.getStopFlag());//, false
        }
    }

    private void sendNotice(TaskNodeEntity taskNodeEntity, TaskExecuteEntity taskExecuteEntity, String content) {
        Patient patient = new Patient();
        Map<String, String> patientOrderUser = patientMapper.getPatientOrderUser(taskExecuteEntity.getInpatorderdataId());
        patient.setInpatNum(taskExecuteEntity.getInpatNum());
        patient.setHealthNum(patientOrderUser.get("healthNum"));
        patient.setMedicalNum(patientOrderUser.get("medicalNum"));
        patient.setBedNo(Integer.valueOf(patientOrderUser.get("bedNo")));
        patient.setOutpatNum(taskExecuteEntity.getOutpatNum());
        patient.setPatName(patientOrderUser.get("patName"));
        patient.setDeptId(patientOrderUser.get("deptId"));
        patient.setWardDeptId(patientOrderUser.get("wardDeptId"));
        TargetUser targetUser = new TargetUser();
        targetUser.setUserId(patientOrderUser.get("userId"));
        targetUser.setUserName(patientOrderUser.get("userName"));
        Notification notification = new Notification();
        notification.setNotifyDate(new Date());
        notification.setNotifyLevel(taskNodeEntity.getNotifyLevel());
        notification.setPatient(patient);
        notification.setTargetUser(targetUser);
        notification.setType(patientOrderUser.get("orderType"));
        if (StringUtils.isNotBlank(content)) {
            notification.setContent(content);
        } else {
            NodeEntity nodeEntity = nodeMapper.selectByPrimaryKey(taskNodeEntity.getNodeId());
            notification.setContent(patientOrderUser.get("bedNo") + "床，" + nodeEntity.getNodeName() + "已完成。");
        }
        notification.setId(new ObjectId());
        notification.setNotificationId(UUIDUtil.randomString());
        mongoTemplate.save(notification);
        sendWorkflow(Constant.TOPIC_TYPE_NOTIFICATION, JSON.toJSONString(notification));
    }

    private List<CompletableFuture<Tuple2<String, JSONObject>>> getDatasetMap2(List<ConditionDetailsDTO> taskConditionElements, String inpatNum) {
        return taskConditionElements.parallelStream().filter(conditionDetailsDTO -> conditionDetailsDTO.getQuoteDatasetId() != null)
                .map(ConditionDetailsDTO::getQuoteDatasetId).distinct().map(datasetId -> CompletableFuture.supplyAsync(() -> {
                    long t1 = System.currentTimeMillis();
                    Map<String, String> params = new HashMap<>();
                    params.put("DATASET_ID", datasetId);
                    params.put("inpatNum", inpatNum);
                    Result result = dataSetValueCommonService.commonDataSetValue(params);
                    long t2 = System.currentTimeMillis();
                    logger.info("查询第三方接口 {} 数据耗时：{} ms", JSON.toJSONString(params), t2 - t1);
                    if (result.getCode() == 200) {
                        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
                        return Tuples.of(datasetId, data);
                    } else {
                        return null;
                    }
                })).collect(Collectors.toList());
    }

    private Map<String, Map<String, Object>> getDatasetMap(List<ConditionDetailsDTO> taskConditionElements, String inpatNum) {
        Map<String, Map<String, Object>> datasetMap = new HashMap<>();
        List<String> dataSetList = taskConditionElements.stream().filter(conditionDetailsDTO -> conditionDetailsDTO.getQuoteDatasetId() != null)
                .map(ConditionDetailsDTO::getQuoteDatasetId).distinct().collect(Collectors.toList());
        for (String datasetId : dataSetList) {
            Map<String, String> params = new HashMap<String, String>();
            params.put("DATASET_ID", datasetId);
            params.put("inpatNum", inpatNum);
            Result result = dataSetValueCommonService.commonDataSetValue(params);
            if (result.getCode() == 200) {
                Map map = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Map.class);
                datasetMap.put(datasetId, map);
            }
        }
        return datasetMap;
    }

    private String matchQuoteDataSetValue(String formula, List<ConditionDetailsDTO> conditionElements, Map<String, Map<String, Object>> datasetMap) {
        List<ConditionDetailsDTO> conditionQuoteElements = conditionElements.stream().filter(conditionDetailsDTO ->
                StringUtils.isNotBlank(conditionDetailsDTO.getQuoteDatasetId()) && StringUtils.isNotBlank(conditionDetailsDTO.getQuoteElementId())).collect(Collectors.toList());
        for (ConditionDetailsDTO conditionElement : conditionQuoteElements) {
            Map<String, Object> dataSetMap = datasetMap.get(conditionElement.getQuoteDatasetId());
            if (dataSetMap != null) {
                String dataCode = "";
                String dataValue = "";
                Object value = dataSetMap.get(conditionElement.getQuoteElementId());
                if (value != null) {
                    switch (conditionElement.getElementDataType()) {
                        case TYPE_SIGNLE_SELECTION:
                        case TYPE_MULTIPLE_SELECTION:
                            try {
                                String[] dataPair = value.toString().split(SPECIAL_SPLITER);
                                if (dataPair.length == 2) {
                                    dataCode = dataPair[0];
                                    dataValue = dataPair[1];
                                } else {
                                    // 麻醉方法代码只能返回文本
                                    dataValue = value.toString().replaceAll(SPECIAL_SPLITER, "");
                                }
                            } catch (Exception e) {
                                logger.error("赋值出错。", e);
                            }
                            break;
                        default:
                            dataValue = value.toString();
                    }
                }
                if (StateEnum.SIMPLE_SEL.getValue().equals(conditionElement.getElementDataType())
                        || StateEnum.CHECK_BOX.getValue().equals(conditionElement.getElementDataType())) {   //下拉框或勾选匹配dataCode
                    boolean match = conditionElement.getDataCode().equals(dataCode);
                    formula = formula.replace(conditionElement.getConditionDetailId(), String.valueOf(match));
                } else if (StateEnum.MULTI_SEL.getValue().equals(conditionElement.getElementDataType())) {//多选
                    boolean match = Arrays.asList(dataCode.split(",")).containsAll(Arrays.asList(conditionElement.getDataCode().split(",")));
                    formula = formula.replace(conditionElement.getConditionDetailId(), String.valueOf(match));
                } else {    //数值型直接替换公式
                    if (StringUtils.isBlank(dataValue)) {
                        String temp = formula.substring(formula.indexOf(conditionElement.getConditionDetailId()));
                        int index = StringUtils.indexOfAny(temp, "&&", "||", ")");
                        if (index > 0) {
                            formula = formula.replace(temp.substring(0, index), "false");
                        } else {
                            formula = formula.replace(temp, "false");
                        }
                    } else {
                        formula = formula.replace(conditionElement.getConditionDetailId(), dataValue);
                    }
                }
            } else {
                formula = formula.replace(conditionElement.getConditionDetailId(), "false");
            }
        }
        return formula;
    }

    private String matchQuoteTplDetail(String formula, List<ConditionDetailsDTO> conditionElements, String inpatorderdataId, String inpatNum,
                                       TaskExecuteEntity taskExecuteEntity, String taskExeDetailId, String orderQrCode) {
        List<ConditionDetailsDTO> conditionQuoteTplElements = conditionElements.stream().filter(conditionDetailsDTO ->
                StringUtils.isNotBlank(conditionDetailsDTO.getQuoteTplDetailId())).collect(Collectors.toList());
        for (ConditionDetailsDTO conditionElement : conditionQuoteTplElements) {
            //查询应用模板数据元
            String dataCode = "";
            String dataValue = "";
            JSONArray priorityArray = JSONArray.parseArray(conditionElement.getQuoteTplDetailId());
            JSONArray totalArray = (JSONArray) priorityArray.get(0);
            JSONObject quoteRule = (JSONObject) totalArray.get(0);
            String quoteCtlId = quoteRule.getString("quoteCtlId");
            List<OrdersFileIndexDataEntity> refDataList;
            if (StateEnum.CATALOG_ORDERS.getValue().equals(quoteRule.getString("quoteNodeType"))) {
                Map<String, String> fileDataByOrder = emrFileMapper.getFileDataByOrder(inpatorderdataId);
                refDataList = emrFileMapper.queryRefOrderData(quoteRule.getString("quoteId"), inpatorderdataId, inpatNum,
                        quoteRule.getString("quoteAll"), quoteRule.getString("isDesc"), fileDataByOrder.get("emrFileId"), fileDataByOrder.get("elementId"));
            } else if (StateEnum.CATALOG_TASKS.getValue().equals(quoteRule.getString("quoteNodeType"))) {
                refDataList = emrFileMapper.queryRefBatchDataForTask(quoteRule.getString("quoteId"), quoteCtlId, quoteRule.getString("quoteAll"), quoteRule.getString("isDesc"), orderQrCode);
            } else {
                refDataList = emrFileMapper.queryRefData(quoteRule.getString("quoteId"), quoteCtlId, inpatNum, quoteRule.getString("quoteAll"), quoteRule.getString("isDesc"));
            }

            if (!refDataList.isEmpty()) {
                dataCode = refDataList.get(0).getDataCode();
                dataValue = refDataList.get(0).getDataValue();
            }
            //匹配医嘱文书数据元值
            if (StateEnum.SIMPLE_SEL.getValue().equals(conditionElement.getElementDataType())
                    || StateEnum.CHECK_BOX.getValue().equals(conditionElement.getElementDataType())) {   //下拉框或勾选项匹配dataCode
                boolean match = conditionElement.getDataCode().equals(dataCode);
                formula = formula.replace(conditionElement.getConditionDetailId(), String.valueOf(match));
            } else if (StateEnum.MULTI_SEL.getValue().equals(conditionElement.getElementDataType())) {//多选
                boolean match = Arrays.asList(dataCode.split(",")).containsAll(Arrays.asList(conditionElement.getDataCode().split(",")));
                formula = formula.replace(conditionElement.getConditionDetailId(), String.valueOf(match));
            } else {    //数值型直接替换公式
                if (StringUtils.isBlank(dataValue)) {
                    String temp = formula.substring(formula.indexOf(conditionElement.getConditionDetailId()));
                    int index = StringUtils.indexOfAny(temp, "&&", "||", ")");
                    if (index > 0) {
                        formula = formula.replace(temp.substring(0, index), "false");
                    } else {
                        formula = formula.replace(temp, "false");
                    }
                } else {
                    formula = formula.replace(conditionElement.getConditionDetailId(), dataValue);
                }
            }
        }
        return formula;
    }

    private String matchDataValue(String formula, List<ConditionDetailsDTO> conditionElements, List<FileIndexDataDTO> dataEntityList) {
        List<ConditionDetailsDTO> conditionCommonElements = conditionElements.stream().filter(conditionDetailsDTO ->
                StringUtils.isBlank(conditionDetailsDTO.getQuoteDatasetId()) && StringUtils.isBlank(conditionDetailsDTO.getQuoteElementId()) &&
                        StringUtils.isBlank(conditionDetailsDTO.getQuoteTplDetailId()) && StringUtils.isNotBlank(conditionDetailsDTO.getElementId())).collect(Collectors.toList());
        for (ConditionDetailsDTO conditionElement : conditionCommonElements) {
            if (StateEnum.SIMPLE_SEL.getValue().equals(conditionElement.getElementDataType())
                    || StateEnum.CHECK_BOX.getValue().equals(conditionElement.getElementDataType())) {   //下拉框或勾选匹配dataCode
                boolean match = dataEntityList.stream().anyMatch(fileData -> fileData.getElementId().equals(conditionElement.getElementId()) &&
                        conditionElement.getDataCode().equals(fileData.getDataCode()));
                formula = formula.replace(conditionElement.getConditionDetailId(), String.valueOf(match));
            } else if (StateEnum.MULTI_SEL.getValue().equals(conditionElement.getElementDataType())) {//多选
                String dataCode = dataEntityList.stream().filter(fileData -> fileData.getElementId().equals(conditionElement.getElementId()))
                        .map(fileData -> fileData.getDataCode()).collect(Collectors.joining());
                boolean match = Arrays.asList(dataCode.split(",")).containsAll(Arrays.asList(conditionElement.getDataCode().split(",")));
                formula = formula.replace(conditionElement.getConditionDetailId(), String.valueOf(match));
            } else {    //数值型直接替换公式
                String dataValue = dataEntityList.stream().filter(fileData -> fileData.getElementId().equals(conditionElement.getElementId())
                        && StringUtils.isNotBlank(fileData.getDataValue())).map(fileData -> fileData.getDataValue()).collect(Collectors.joining());
                if (StringUtils.isBlank(dataValue)) {
                    String temp = formula.substring(formula.indexOf(conditionElement.getConditionDetailId()));
                    int index = StringUtils.indexOfAny(temp, "&&", "||", ")");
                    if (index > 0) {
                        formula = formula.replace(temp.substring(0, index), "false");
                    } else {
                        formula = formula.replace(temp, "false");
                    }
                } else {
                    formula = formula.replace(conditionElement.getConditionDetailId(), dataValue);
                }
            }
        }
        return formula;
    }

    public void sendAppMessage(Map<String, String> patientInfo, String orderName, String actionName, String type) {
        String inpatNum = patientInfo.get("inpatNum");
        String content = patientInfo.get("wardName").toString() + patientInfo.get("bedNo").toString() + "床" + orderName + "医嘱" + actionName;
        logger.info("医嘱状态变更发送App消息:{}", content);
        List<String> accountList = nurseTeamService.querySendUser(inpatNum, "nurse");
        List<Notification> list = new CopyOnWriteArrayList<>();
        accountList.parallelStream().forEach(account -> {
            Notification notification = new Notification();
            notification.setNotifyDate(new Date());
            notification.setContent(content);
            notification.setPatient(new Patient(inpatNum));
            notification.setType(ConstantEnum.NOTIFICATION_TASK.getKey());
            notification.setContentType(ConstantEnum.NOTIFICATION_TYPE_TEXT.getKey());
            notification.setNotifyLevel("2");
            notification.setId(new ObjectId());
            notification.setNotificationId(UUIDUtil.randomString());
            notification.setTargetUser(new TargetUser(account));
            PushSocketMessage pushSocketMessage = new PushSocketMessage();
            SocketMessageDTO socketMessageDTO = new SocketMessageDTO();
            socketMessageDTO.setData(JSONUtils.jsonToMap(JSONUtils.beanToJson(notification)));
            socketMessageDTO.setMsgType("text");
            pushSocketMessage.setUserIds(new ArrayList<>(Arrays.asList(account)));
            pushSocketMessage.setData(socketMessageDTO);
            HttpClientUtil.sendPost(socketUrl, pushSocketMessage);
            list.add(notification);
        });
        mongoTemplate.insertAll(list);
    }

    public void updateGroupOrders(PatientOrdersEntity patientOrdersEntity) {
        Condition condition = new Condition(PatientOrdersEntity.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("inpatNum", patientOrdersEntity.getInpatNum());
        criteria.andEqualTo("orderNo", patientOrdersEntity.getOrderNo());
        PatientOrdersEntity updateOrder = new PatientOrdersEntity();
        updateOrder.setExecStatus(patientOrdersEntity.getExecStatus());
        updateOrder.setExecPersonId(patientOrdersEntity.getExecPersonId());
        updateOrder.setExecDatetime(patientOrdersEntity.getExecDatetime());
        patientOrderMapper.updateByConditionSelective(updateOrder, condition);
    }

    private void createInjections2(TaskExecuteDetailEntity taskExecuteDetailEntity, PatientOrdersEntity patientOrdersEntity, String orderQrCode, String taskId, Integer batchNo, String userId, OrdersFileIndexEntity emrFileIndexEntity) {

        try {
            //线程暂停等主线程执行完成
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (StringUtils.isNotBlank(orderQrCode)) {
            orderQrCode = patientOrdersEntity.getInpatorderdataId();
        }
        Integer lastBatchNo = taskExecuteBatchMapper.getMaxBatchNo(taskExecuteDetailEntity.getTaskExecuteDetailId(), taskExecuteDetailEntity.getTaskNodeId());
        if (null != lastBatchNo) {
            batchNo = lastBatchNo;
        } else {
            batchNo = 1;
        }

        Integer lastSeriNo = taskExecuteBatchMapper.getMaxSerialNo(patientOrdersEntity.getInpatorderdataId(), batchNo);
        if (null != patientOrdersEntity && StringUtils.isNotBlank(patientOrdersEntity.getInpatorderdataId())) {
            //
            Map<String, String> map = taskExecuteMapper.queryCycleOrderInfo(patientOrdersEntity.getInpatorderdataId());
            if (!CollectionUtils.isEmpty(map)) {
                String orderType = map.get("orderType");
                if (OrderStatusEnum.ORDER_TYPE_ONE.getValue().equals(orderType)) {
                    Map<String, String> InjectMap = taskExecuteMapper.getInjectTaskIdAndNodeId(taskId);
                    if (OrderStatusEnum.ORDER_TYPE_ONE.getValue().equals(orderType)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String nowDateStr = sdf.format(new Date()).substring(0, 10) + " 00:00:00";
                        Date nowDate = DateUtil.stringToDate(nowDateStr);
                        Date nextDay = DateUtil.getDateAfter(nowDate, 1);
                        if (null != map.get("TIMEMODE")) {
                            Date nextExecDate = nowDate;
                            Date finallyDate = null;
                            Date startTime = DateUtil.stringToDate(map.get("START_TIME"));
                            AtomicInteger atomicInteger = new AtomicInteger(1);
                            AtomicInteger atomicInteger2 = new AtomicInteger(1);

                            AtomicInteger hourNum = new AtomicInteger(0);
                            AtomicInteger weekNum = new AtomicInteger(0);
                            if ("0".equals(map.get("TIMEMODE"))) {
                                //timemode 0指定时间模式
                                Date nextDate = DateUtil.increasedSeconds(nowDate, Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
                                if (nextDate.before(nextDay)) {
                                    nextDate = nextDay;
                                }
                                CronDescriber cronDescriber = JSONObject.parseObject(map.get("CRON_DESCRIBER"), CronDescriber.class);
                                hourNum.set(cronDescriber.getSpecifiedHourNum());
                                weekNum.set(cronDescriber.getSpecifiedDowNum());
                                String expression = CronUtil.createCronExpression(cronDescriber, null);
                                CronExpression cronExpression = null;
                                try {
                                    cronExpression = new CronExpression(expression);
                                } catch (ParseException e) {
                                    logger.error("转换corn失败:{}", e);
                                }
                                //计划结束时间
                                if (null == map.get("PLAN_END_DATETIME")) {
                                    map.put("PLAN_END_DATETIME", "2999-01-01 00:00:00");
                                }
                                Date planEndTime = null;
                                try {
                                    planEndTime = sdf.parse(map.get("PLAN_END_DATETIME"));
                                } catch (ParseException e) {
                                    logger.error("PLAN_END_DATETIME 格式化失败:{}", e);
                                }


                                //获得计划开始时间
                                int startTimes = 0;
                                Date beginDatetime = DateUtil.stringToDate(map.get("PLAN_BEGIN_DATETIME"));
                                Date startNextDay = DateUtil.getDateAfter(beginDatetime, 1);
                                Date startDate = cronExpression.getNextValidTimeAfter(beginDatetime);
                                int startNum = 0;
                                while (null != startDate && startDate.before(startNextDay) && !map.get("PLAN_BEGIN_DATETIME").substring(0, 10).equals(DateFormatUtils.format(new Date(), "yyyy-MM-dd"))) {
                                    startTimes++;
                                    startNum = 1;
                                    startDate = cronExpression.getNextValidTimeAfter(startDate);
                                }

                                while (nextExecDate.before(nextDate)) {
                                    nextExecDate = cronExpression.getNextValidTimeAfter(nextExecDate);
                                    if (nextExecDate.before(nextDate) || nextExecDate.equals(nextDate)) {
                                        //此次执行时间需要在计划开始时间之后
                                        if (nextExecDate.after(DateUtil.stringToDate(map.get("PLAN_BEGIN_DATETIME"))) && (nextExecDate.before(planEndTime) || nextExecDate.equals(planEndTime))) {

                                            StringBuffer qrCodeSerialNo = new StringBuffer();
                                            int cycleAllNum = hourNum.get() * (weekNum.get() == 0 ? 1 : weekNum.get()); //Q4H = 6 , TID = 3 , TIW = 3
                                            int cycleNum = cycleAllNum / Integer.valueOf(map.get("EXE_NUMBER"));//Q4H = 6 , TID = 1 , TIW = 1 || EXE_CYCLE_STAMP（Q4H = 14400 , TID = 86400 , TIW = 604800)
                                            long allNums = (cycleAllNum * ((((nextExecDate.getTime() - startTime.getTime()) / 1000 / Integer.parseInt(map.get("EXE_CYCLE_STAMP"))) / cycleNum) - 1));
                                            long cycle = startTimes + (allNums < 0 ? 0 : allNums) + 1;
                                            if (cycle != atomicInteger.longValue() && atomicInteger.get() == 1) {
                                                atomicInteger2 = new AtomicInteger(1);

                                                atomicInteger.set((int) cycle);
                                            }
                                            TaskExecuteBatchEntity taskBatch = taskExecuteBatchMapper.queryTaskBatch(atomicInteger.get(), map.get("INPATORDERDATA_ID"));
                                            if (null != taskBatch && !map.get("PLAN_BEGIN_DATETIME").substring(0, 10).equals(DateFormatUtils.format(new Date(), "yyyy-MM-dd"))) {
                                                finallyDate = nextExecDate;
                                                continue;
                                            }
                                            qrCodeSerialNo.append("_").append(atomicInteger.get()).append("_").append(atomicInteger2.get());


                                            TaskExecuteBatchEntity taskExecuteBatchEntity = insertExecBatchEntity(taskExecuteDetailEntity, patientOrdersEntity, atomicInteger.getAndIncrement(), nextExecDate, lastSeriNo, orderQrCode + qrCodeSerialNo.toString());

                                            //触发下一个任务节点
                                            createNextTaskNode(taskExecuteBatchEntity.getTaskExecuteDetailId(), taskExecuteBatchEntity.getBatchNo(), userId, "", "", DateUtil.dateToString(nextExecDate, "yyyy-MM-dd HH:mm:ss"), taskExecuteBatchEntity.getQrCode(),null);//, false
                                            lastSeriNo += 2;
                                            batchNo += 1;
                                        }
                                        finallyDate = nextExecDate;
                                    }
                                }
                                if (null != finallyDate) {
                                    taskExecuteMapper.updateOrderExecuteTime(map.get("INPATORDERDATA_ID"), finallyDate);
                                }
                            } else if ("1".equals(map.get("TIMEMODE"))) {
                                //timemode 1 固定间隔时间模式
                                Date planEndTime = null;
                                Date nextDate = null;
                                try {
                                    if (null == map.get("PLAN_END_DATETIME")) {
                                        map.put("PLAN_END_DATETIME", "2999-01-01 00:00:00");
                                    }
                                    planEndTime = sdf.parse(map.get("PLAN_END_DATETIME"));
                                    if (null == map.get("LAST_EXECUTE_TIME") || "".equals(map.get("LAST_EXECUTE_TIME"))) {
                                        nextDate = DateUtil.increasedSeconds(sdf.parse(map.get("PLAN_BEGIN_DATETIME")), Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
                                    } else {
                                        nextDate = DateUtil.increasedSeconds(sdf.parse(map.get("LAST_EXECUTE_TIME")), Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
                                    }
                                } catch (ParseException e) {
                                    logger.error("时间格式化异常:{}", e);
                                }
                                Integer serialNo = taskExecuteDetailEntity.getSerialNo();
                                while (nextDate.getTime() <= nextDay.getTime() && nextDate.getTime() <= planEndTime.getTime()) {
                                    if (nextDate.after(DateUtil.stringToDate(map.get("PLAN_BEGIN_DATETIME")))) {

                                        String qrCodeSerialNo = "";
                                        long cycle = (nextDate.getTime() - startTime.getTime()) / 1000 / Integer.parseInt(map.get("EXE_CYCLE_STAMP")) + 1;
                                        if (cycle != atomicInteger.longValue()) {
                                            atomicInteger2 = new AtomicInteger(1);
                                            atomicInteger = new AtomicInteger((int) cycle);
                                        }
                                        if (cycle == atomicInteger.longValue()) {
                                            serialNo = atomicInteger2.getAndIncrement();
                                            qrCodeSerialNo = patientOrdersEntity.getInpatorderdataId() + "_" + cycle + "_" + serialNo;

                                        }

                                        TaskExecuteBatchEntity taskExecuteBatchEntity = insertExecBatchEntity(taskExecuteDetailEntity, patientOrdersEntity, batchNo, nextDate, lastSeriNo, qrCodeSerialNo);
                                        lastSeriNo += 1;
                                        batchNo += 1;
                                        createNextTaskNode(taskExecuteBatchEntity.getTaskExecuteDetailId(), taskExecuteBatchEntity.getBatchNo(), userId, "", "", DateUtil.dateToString(nextDate, "yyyy-MM-dd HH:mm:ss"), taskExecuteBatchEntity.getQrCode(),null);//, false
                                    }
                                    finallyDate = nextDate;
                                    nextDate = DateUtil.increasedSeconds(nextDate, Integer.parseInt(map.get("EXE_CYCLE_STAMP")));
                                }
                                if (null != finallyDate) {
                                    taskExecuteMapper.updateOrderExecuteTime(map.get("INPATORDERDATA_ID"), finallyDate);
                                }
                            }
                        }
                    }

                } else {
                    //下达医嘱时间和创建下一任务时间为同一时间、延后2秒(创建医嘱任务时已经延时了1s)
                    Date nextExecDate = DateUtil.stringToDate(map.get("createTime"));
//                nextExecDate = DateUtil.increasedSeconds(nextExecDate,2);
                    Map<String, String> InjectMap = taskExecuteMapper.getInjectTaskIdAndNodeId(taskId);
                    TaskNodeEntity taskNodeEntity = new TaskNodeEntity();
                    taskNodeEntity.setTaskId(InjectMap.get("TASK_ID"));
                    taskNodeEntity.setTaskNodeId(InjectMap.get("TASK_NODE_ID"));
                    //执行任务流程
                    TaskExecuteBatchEntity taskExecuteBatchEntity = insertExecBatchEntity(taskExecuteDetailEntity, patientOrdersEntity, batchNo, nextExecDate, lastSeriNo, orderQrCode + "_1");
//                    TaskExecuteDetailEntity taskExecuteDetail = createTaskExecute2(UUIDUtil.randomString(), patientOrdersEntity.getInpatorderdataId(),
//                            TaskEnum.EXECUTED.getValue(), taskNodeEntity, emrFileIndexEntity, nextExecDate, orderQrCode + "_1");
                    //触发下一个任务节点
                    createNextTaskNode(taskExecuteBatchEntity.getTaskExecuteDetailId(), batchNo, userId, "", null, "", orderQrCode + "_1",null);//, false
                }
            }
        }
    }

    private void sendQueryNotify(String userId) {


        Patient p = new Patient();
        TargetUser targetUser = new TargetUser();
        targetUser.setUserId(userId);
        Map<String, String> user = patientOrderMapper.getUser(userId);
        targetUser.setUserName(user.get("userName"));
        Notification notification = new Notification();
        notification.setNotifyDate(new Date());
        notification.setPatient(p);
        notification.setTargetUser(targetUser);
        notification.setType(ConstantEnum.NOTIFICATION_CHECK_TABLE.getKey());
        notification.setContent("{\"queryFlag\":true}");
        notification.setId(new ObjectId());
        notification.setNotificationId(UUIDUtil.randomString());

        sendWorkflow(Constant.TOPIC_TYPE_CHECK_APPROVAL, JSON.toJSONString(notification));
        logger.info("流程结束发送通知消息");
    }

    private void sendWorkflow(String topic, String jsonMsg) {
        ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topic, jsonMsg);
        future.addCallback(result -> logger.info("生产者成功发送消息到topic:{} partition:{}的消息", result.getRecordMetadata().topic(), result.getRecordMetadata().partition()),
                ex -> logger.error("生产者发送消失败，原因：{}", ex.getMessage()));
    }

    private TaskExecuteBatchEntity insertExecBatchEntity(TaskExecuteDetailEntity taskExecuteDetailEntity, PatientOrdersEntity patientOrdersEntity, Integer batchNo, Date nextExecDate, long serialNo, String qrCodeSerialNo) {
        TaskExecuteBatchEntity batchEntity = new TaskExecuteBatchEntity();
        batchEntity.initAdd();
        batchEntity.setTaskBatchId(UUIDUtil.randomString());
        batchEntity.setEmrFileId(taskExecuteDetailEntity.getEmrFileId());
        batchEntity.setStatus(TaskEnum.UNEXECUTED.getValue());
        batchEntity.setInpatorderdataId(patientOrdersEntity.getInpatorderdataId());
        batchEntity.setQrCode(qrCodeSerialNo);
        batchEntity.setTaskNodeId(taskExecuteDetailEntity.getTaskNodeId());
        batchEntity.setTaskExecuteId(taskExecuteDetailEntity.getTaskExecuteId());
        batchEntity.setSerialNo((int) serialNo);
        batchEntity.setBatchNo(batchNo.longValue());
        batchEntity.setBarCode(taskExecuteDetailEntity.getBarCode());
        batchEntity.setBatchFlag(ConstantEnum.BATCH_FLAG_1.getKey());
        batchEntity.setTaskExecuteDetailId(taskExecuteDetailEntity.getTaskExecuteDetailId());
        batchEntity.setStartDatetime(new Timestamp(nextExecDate.getTime()));
        taskExecuteBatchMapper.insertSelective(batchEntity);
        return batchEntity;
    }

    private List<EmrFileData> convertData(List<Map<String, Object>> list, Map<String, String> currentUser, String preDataCode, String preDataValue) {
        return list.parallelStream().map(map -> {
            // 医嘱类型如果不是不可修改 将和上一个医嘱类型保持一致
            if (StringUtils.isNoneEmpty((String) map.get("VAR_CODE"), preDataCode, preDataValue)
                    && !((String) map.get("ELEMENT_PROPERTY")).contains("\"editIdentification\":\"1\"")
                    && map.get("VAR_CODE").equals("yz_type")) {
                map.put("DATA_CODE", preDataCode);
                map.put("DATA_VALUE", preDataValue);
            }
            EmrFileData data = new EmrFileData();
            OrdersFileIndexDataEntity dataEntity = new OrdersFileIndexDataEntity();
            dataEntity.setFileIndexDataId((String) map.get("FILE_INDEX_DATA_ID"));
            try {
                if (map.get("GMT_CREATE") instanceof TIMESTAMP)
                    dataEntity.setCreateTime(((TIMESTAMP) map.get("GMT_CREATE")).timestampValue());
                else
                    dataEntity.setCreateTime(((Date) map.get("GMT_CREATE")));
            } catch (SQLException e) {
                logger.error("转换对象出错。", e);
            }
            try {
                if (map.get("GMT_MODIFY") instanceof TIMESTAMP)
                    dataEntity.setModifyTime(((TIMESTAMP) map.get("GMT_MODIFY")).timestampValue());
                else
                    dataEntity.setModifyTime(((Date) map.get("GMT_MODIFY")));
            } catch (SQLException e) {
                logger.error("转换对象出错。", e);
            }
            dataEntity.setSortId((map.get("SORT_ID")) == null ? 0 : ((Number) map.get("SORT_ID")).intValue());
            dataEntity.setElementId((String) map.get("ELEMENT_ID"));
            dataEntity.setParentElementId((String) map.get("PARENT_ELEMENT_ID"));
            dataEntity.setQuoteDatasetId((String) map.get("QUOTE_DATASET_ID"));
            dataEntity.setQuoteElementId((String) map.get("QUOTE_ELEMENT_ID"));
            dataEntity.setDataCode((String) map.get("DATA_CODE"));
            dataEntity.setParentFileIndexDataId((String) map.get("PARENT_FILE_INDEX_DATA_ID"));
            dataEntity.setBaseTplDetailId((String) map.get("BASE_TPL_DETAIL_ID"));
            dataEntity.setQuoteTplDetailId((String) map.get("QUOTE_TPL_DETAIL_ID"));
            String dataValue = "";
            if (map.get("DATA_VALUE_STR") != null) {
                dataValue = (String) map.get("DATA_VALUE_STR");
            } else {
                try {
                    if (map.get("DATA_VALUE") != null) {
                        if (map.get("DATA_VALUE") instanceof Clob) {
                            Clob clob = (Clob) map.get("DATA_VALUE");
                            BufferedReader reader = new BufferedReader(clob.getCharacterStream());
                            dataValue = FileCopyUtils.copyToString(reader);
                        } else
                            dataValue = (String) map.get("DATA_VALUE");
                    }
                } catch (SQLException | IOException e) {
                    logger.error("转换对象出错。", e);
                }
            }
            dataEntity.setDataValue(dataValue);
            dataEntity.setFormatDataValue((String) map.get("FORMAT_DATA_VALUE"));
            dataEntity.setPrintIdentification((String) map.get("PRINT_IDENTIFICATION"));
            dataEntity.setShowIdentification((String) map.get("SHOW_IDENTIFICATION"));
            dataEntity.setDeleteIdentification((String) map.get("DELETE_IDENTIFICATION"));
            dataEntity.setElementProperty((String) map.get("ELEMENT_PROPERTY"));
            dataEntity.setMedicalId((String) map.get("MEDICAL_ID"));
            dataEntity.setUnit((String) map.get("UNIT"));
            dataEntity.setExtendedField(map.get("EXTENDED_FIELD") == null ? "" : map.get("EXTENDED_FIELD").toString());
            dataEntity.setFormatDataValue(map.get("FORMAT_DATA_VALUE") == null ? "" : map.get("FORMAT_DATA_VALUE").toString());
            data.setNeedChanged(map.get("NEED_CHANGED") == null ? "1" : map.get("NEED_CHANGED").toString());
            data.setFileIndexDataEntity(dataEntity);
            data.setTplDetailId((String) map.get("TPL_DETAIL_ID"));
            if (currentUser != null && StringUtils.isNotBlank(dataEntity.getElementProperty())) {
                JSONObject property = JSONObject.parseObject(dataEntity.getElementProperty());
                if (SWITCH_ON.equals(property.get("currentUser"))) {
                    dataEntity.setDataCode(currentUser.get("personId"));
                    dataEntity.setDataValue(currentUser.get("userName"));
                }
                if (SWITCH_ON.equals(property.get("currentDept"))) {
                    dataEntity.setDataCode(currentUser.get("deptId"));
                    dataEntity.setDataValue(currentUser.get("deptName"));
                }
                if (SWITCH_ON.equals(property.get("currentTimeStamp"))) {
                    dataEntity.setDataValue(DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm"));
                }
            }

            // 补充数据元属性
            Element element = new Element();
            element.setId((String) map.get("ELEMENT_ID"));
            element.setName((String) map.get("ELEMENT_NAME"));
            if (StringUtils.isBlank(element.getName())) {
                element.setDataValue(dataEntity.getDataValue());
            }
            element.setType((String) map.get("ELEMENT_DATA_TYPE_ID"));
            element.setMin(map.get("MIN_VALUE") == null ? null : ((Number) map.get("MIN_VALUE")).doubleValue());
            element.setMax(map.get("MAX_VALUE") == null ? null : ((Number) map.get("MAX_VALUE")).doubleValue());
            element.setUnit(map.get("ELEMENT_UNIT") == null ? null : map.get("ELEMENT_UNIT").toString());
            element.setVarCode((String) map.get("VAR_CODE"));
            element.setMedicalId(dataEntity.getMedicalId());
            element.setFormat((String) map.get("ELEMENT_PROPERTY_FORMAT"));
            element.setElementPropertyFormat((String) map.get("ELEMENT_PROPERTY_FORMAT"));
            element.setIsPreDiag(map.get("IS_PRE_DIAG") == null ? null : map.get("IS_PRE_DIAG").toString());
            data.setElement(element);

            data.setEmrFileDataList(new ArrayList<>());
            return data;
        }).collect(Collectors.toList());
    }

    private void updateQuoteDatasetValue(Map<String, Map<String, Object>> datasetMap, EmrFileData emrFileData, Boolean trigger) {
        OrdersFileIndexDataEntity dataEntity = emrFileData.getFileIndexDataEntity();
        Element element = emrFileData.getElement();
        Map<String, Object> dataset = datasetMap.get(dataEntity.getQuoteDatasetId());
        if (dataset != null) {
            Object value = dataset.get(dataEntity.getQuoteElementId());
            if (value != null) {
                switch (element.getType()) {
                    case TYPE_SIGNLE_SELECTION:
                    case TYPE_MULTIPLE_SELECTION:
                        try {
                            String[] dataPair = value.toString().split(SPECIAL_SPLITER);
                            if (dataPair.length == 2) {
                                dataEntity.setDataCode(dataPair[0]);
                                dataEntity.setDataValue(dataPair[1]);
                                emrFileData.setFirstTrigger(trigger);
                            } else {
                                // 麻醉方法代码只能返回文本
                                dataEntity.setDataValue(value.toString().replaceAll("\\$€\\$€\\$", ""));
                            }
                        } catch (Exception e) {
                            logger.error("赋值出错。", e);
                        }
                        break;
                    default:
                        dataEntity.setDataValue(value.toString());
                }
            }
        }
    }

    public List<EmrFileData> getEmrFileData(String emrFileId, String parentFileIndexDataId, Map<String, String> currentUser) {
        long t1 = System.currentTimeMillis();
        List<Map<String, Object>> list = emrFileMapper.getAllEmrDataEntity(emrFileId, parentFileIndexDataId);

        long t2 = System.currentTimeMillis();
        logger.info("{} 从数据库获取{}条数据时间： {} ms", emrFileId, list.size(), t2 - t1);
        List<EmrFileData> emrFileDataList = convertData(list, currentUser, null, null);
        emrFileDataList.stream().forEach(emrFileData -> {
            Element element = emrFileData.getElement();
            // 补充全部勾选项
            if (element.getElementPropertyFormat() != null && element.getElementPropertyFormat().indexOf("\"formatValue\":\"2\"") > -1) {
                element.setSelections(emrFileMapper.getAllSelections(element.getId()));
            }
        });
        return emrFileDataList;
    }

    private List<EmrFileData> getOrderFileData(String emrFileId, String parentFileIndexDataId, Map<String, String> currentUser) {
        long t1 = System.currentTimeMillis();
        List<Map<String, Object>> list = emrFileMapper.getAllOrderDataEntity(emrFileId, parentFileIndexDataId);
        long t2 = System.currentTimeMillis();
        logger.info("{} 从数据库获取{}条数据时间： {} ms", emrFileId, list.size(), t2 - t1);
        List<EmrFileData> emrFileDataList = convertData(list, currentUser, null, null);
        emrFileDataList.stream().forEach(emrFileData -> {
            Element element = emrFileData.getElement();
            // 补充全部勾选项
            if (element.getElementPropertyFormat() != null && element.getElementPropertyFormat().indexOf("\"formatValue\":\"2\"") > -1) {
                element.setSelections(emrFileMapper.getAllSelections(element.getId()));
            }
        });
        return emrFileDataList;
    }
}
